package com.tianhai.db;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * 简单测试类 - 测试DiskManager和Page的基本功能
 */
public class SimpleTest {
    
    public static void main(String[] args) {
        System.out.println("=== 数据库磁盘管理测试开始 ===\n");
        
        DiskManager diskManager = null;
        
        try {
            // 1. 创建DiskManager实例
            System.out.println("【步骤1】创建DiskManager实例");
            String dbFilePath = "data.db";
            diskManager = new DiskManager(dbFilePath);
            System.out.println("✓ DiskManager创建成功: " + diskManager);
            System.out.println();
            
            // 2. 分配新页
            System.out.println("【步骤2】分配新页");
            Page page1 = diskManager.allocateNewPage();
            System.out.println("✓ 新页分配成功: " + page1);
            System.out.println("  - 页ID: " + page1.getPageId());
            System.out.println("  - 最大槽位数: " + page1.getMaxSlots());
            System.out.println("  - 槽位大小: " + page1.getSlotSize() + " bytes");
            System.out.println();
            
            // 3. 在页中分配槽位并写入数据
            System.out.println("【步骤3】在页中分配槽位并写入数据");
            
            // 写入第一条数据
            int slot1 = page1.allocateSlot();
            String data1 = "Hello, Database! This is record #1";
            byte[] bytes1 = data1.getBytes(StandardCharsets.UTF_8);
            page1.writeSlot(slot1, bytes1);
            System.out.println("✓ 槽位 " + slot1 + " 写入数据: \"" + data1 + "\"");
            
            // 写入第二条数据
            int slot2 = page1.allocateSlot();
            String data2 = "Welcome to Page Storage System - Record #2";
            byte[] bytes2 = data2.getBytes(StandardCharsets.UTF_8);
            page1.writeSlot(slot2, bytes2);
            System.out.println("✓ 槽位 " + slot2 + " 写入数据: \"" + data2 + "\"");
            
            // 写入第三条数据
            int slot3 = page1.allocateSlot();
            String data3 = "Testing FileChannel I/O - Record #3";
            byte[] bytes3 = data3.getBytes(StandardCharsets.UTF_8);
            page1.writeSlot(slot3, bytes3);
            System.out.println("✓ 槽位 " + slot3 + " 写入数据: \"" + data3 + "\"");
            
            System.out.println("\n当前页状态: " + page1);
            System.out.println("  - 已使用槽位: " + page1.getUsedSlots());
            System.out.println("  - 空闲槽位: " + page1.getFreeSlots());
            System.out.println();
            
            // 4. 将页保存到文件
            System.out.println("【步骤4】将页保存到文件");
            diskManager.writePage(page1);
            System.out.println("✓ 页 " + page1.getPageId() + " 已成功写入文件: " + dbFilePath);
            System.out.println();
            
            // 5. 从文件读取页并验证数据一致性
            System.out.println("【步骤5】从文件读取页并验证数据一致性");
            Page loadedPage = diskManager.readPage(page1.getPageId());
            System.out.println("✓ 页 " + loadedPage.getPageId() + " 从文件读取成功: " + loadedPage);
            System.out.println();
            
            // 验证数据一致性
            System.out.println("【数据一致性验证】");
            boolean allDataValid = true;
            
            // 验证槽位1
            byte[] readBytes1 = loadedPage.readSlot(slot1, bytes1.length);
            String readData1 = new String(readBytes1, StandardCharsets.UTF_8);
            boolean valid1 = data1.equals(readData1);
            System.out.println("槽位 " + slot1 + " 验证: " + (valid1 ? "✓ 通过" : "✗ 失败"));
            System.out.println("  原始数据: \"" + data1 + "\"");
            System.out.println("  读取数据: \"" + readData1 + "\"");
            allDataValid &= valid1;
            
            // 验证槽位2
            byte[] readBytes2 = loadedPage.readSlot(slot2, bytes2.length);
            String readData2 = new String(readBytes2, StandardCharsets.UTF_8);
            boolean valid2 = data2.equals(readData2);
            System.out.println("槽位 " + slot2 + " 验证: " + (valid2 ? "✓ 通过" : "✗ 失败"));
            System.out.println("  原始数据: \"" + data2 + "\"");
            System.out.println("  读取数据: \"" + readData2 + "\"");
            allDataValid &= valid2;
            
            // 验证槽位3
            byte[] readBytes3 = loadedPage.readSlot(slot3, bytes3.length);
            String readData3 = new String(readBytes3, StandardCharsets.UTF_8);
            boolean valid3 = data3.equals(readData3);
            System.out.println("槽位 " + slot3 + " 验证: " + (valid3 ? "✓ 通过" : "✗ 失败"));
            System.out.println("  原始数据: \"" + data3 + "\"");
            System.out.println("  读取数据: \"" + readData3 + "\"");
            allDataValid &= valid3;
            
            System.out.println();
            
            // 验证页元数据
            System.out.println("【页元数据验证】");
            boolean metaValid = true;
            
            boolean pageIdValid = page1.getPageId() == loadedPage.getPageId();
            System.out.println("页ID验证: " + (pageIdValid ? "✓ 通过" : "✗ 失败") + 
                " (原始: " + page1.getPageId() + ", 读取: " + loadedPage.getPageId() + ")");
            metaValid &= pageIdValid;
            
            boolean usedSlotsValid = page1.getUsedSlots() == loadedPage.getUsedSlots();
            System.out.println("已使用槽位验证: " + (usedSlotsValid ? "✓ 通过" : "✗ 失败") + 
                " (原始: " + page1.getUsedSlots() + ", 读取: " + loadedPage.getUsedSlots() + ")");
            metaValid &= usedSlotsValid;
            
            System.out.println();
            
            // 额外测试：多页操作
            System.out.println("【额外测试】多页操作");
            Page page2 = diskManager.allocateNewPage();
            System.out.println("✓ 分配第二个页: " + page2);
            
            int slot = page2.allocateSlot();
            String multiPageData = "Second page data - Testing multiple pages";
            page2.writeSlot(slot, multiPageData.getBytes(StandardCharsets.UTF_8));
            diskManager.writePage(page2);
            System.out.println("✓ 第二个页写入文件成功");
            
            System.out.println("\n当前数据库状态:");
            System.out.println("  - 总页数: " + diskManager.getTotalPages());
            System.out.println("  - 下一个页ID: " + diskManager.getNextPageId());
            System.out.println();
            
            // 最终结果
            System.out.println("===================");
            if (allDataValid && metaValid) {
                System.out.println("✓✓✓ 所有测试通过！");
            } else {
                System.out.println("✗✗✗ 部分测试失败");
            }
            System.out.println("===================");
            
        } catch (IOException e) {
            System.err.println("✗ 发生I/O异常: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("✗ 发生异常: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 清理资源
            if (diskManager != null && !diskManager.isClosed()) {
                try {
                    diskManager.close();
                    System.out.println("\n✓ DiskManager已关闭");
                } catch (IOException e) {
                    System.err.println("✗ 关闭DiskManager时发生异常: " + e.getMessage());
                }
            }
        }
        
        System.out.println("\n=== 测试结束 ===");
    }
}
